package com.s7.widget.widget;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

/**
 * Created by Administrator on 2018\1\10 0010.
 * 曲线图
 */
public class CurveChartView extends View {

    private boolean haveFocuse = false;

    // 默认边距
    private int margin = 40;

    /**
     * 曲线图显示模式
     * 默认显示月数据
     */
    private int model = MODEL_MONTH;
    /**
     * 时间单位
     */
    public static final int MODEL_YEAR = 1;
    public static final int MODEL_MONTH = 2;

    /**
     * 月份中的天数
     */
    private int days = 32;

    // 控件宽高（除去边距后的）
    private int viewWidth, viewHeigth;
    // 每一份的水平、竖直尺寸
    private float averageWidth, averageHeigth;
    // 画笔
    Paint textPaint, lienPaint, bluePaint, whitePaint, garyPaint, coordinatePaint;

    // 曲线路径
    private Path curvePath;

    /**
     * 存储曲线坐标点
     */
    private List<Coordinate> coordinates;

    /**
     * 存储当前点击坐标
     */
    private Coordinate coordinate;

    /**
     * 存储点击状态
     */
    private boolean isFlag = false;

    public CurveChartView(Context context) {
        super(context);
        init();
    }

    public CurveChartView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CurveChartView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        /**
         * 图表文字
         */
        textPaint = new Paint();
        textPaint.setColor(Color.parseColor("#999999"));
        textPaint.setAntiAlias(true);
        textPaint.setTextSize(28);
        textPaint.setStrokeWidth(2f);
        /**
         * 边框线的颜色
         */
        lienPaint = new Paint();
        lienPaint.setColor(Color.parseColor("#999999"));
        lienPaint.setAntiAlias(true);
        lienPaint.setStrokeWidth(4f);
        /**
         * 曲线颜色
         */
        bluePaint = new Paint();
        bluePaint.setColor(Color.parseColor("#2E88CE"));
        bluePaint.setAntiAlias(true);
        bluePaint.setStyle(Paint.Style.STROKE);
        bluePaint.setStrokeWidth(6f);
        /**
         * 背景色
         */
        whitePaint = new Paint();
        whitePaint.setColor(Color.parseColor("#ffffff"));
        whitePaint.setStrokeWidth(2.5f);

        /**
         * 点击位置背景
         */
        garyPaint = new Paint();
        garyPaint.setColor(Color.parseColor("#77333333"));
        garyPaint.setStyle(Paint.Style.FILL);
        garyPaint.setStrokeWidth(2f);

        /**
         * 点击位置文字
         */
        coordinatePaint = new Paint();
        coordinatePaint.setColor(Color.parseColor("#FFFFFF"));
        coordinatePaint.setAntiAlias(true);
        coordinatePaint.setTextSize(28);
        coordinatePaint.setStrokeWidth(2f);

        curvePath = new Path();

        coordinates = new ArrayList<>();
    }

    /**
     * 设置月份(时间轴单位为天时，即：显示一个月的数据)
     * 以当前年月获取月份天数
     */
    public void setMonth(int year, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, month - 1);
        days = calendar.getActualMaximum(Calendar.DAY_OF_MONTH) + 1;

    }

    /**
     * 设置显示模式
     * 1为显示一月每天数据
     * 否则显示一年12月数据
     * @param model
     */
    public void setModel(int model) {
        this.model = model;
        initMeasure();
        invalidate();
    }

    /**
     * 获取时间轴单位长度
     */
    private void initMeasure() {
        viewWidth = getWidth() - margin * 3;
        viewHeigth = getHeight() - margin * 3;
        /**
         * 获取Y轴单位长度
         */
        averageHeigth = viewHeigth / 11;
        /**
         * 获取X轴单位长度
         */
        switch (model) {
            case MODEL_YEAR:
                averageWidth = viewWidth / 13;
                break;
            case MODEL_MONTH:
                averageWidth = viewWidth / days;
                break;
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawGrayBackground(canvas);
        drawYCoordinateNumber(canvas);
        drawYCoordinateLine(canvas);
        drawXCoordinateText(canvas);
        drawXCoordinateLine(canvas);
        drawCurveChart(canvas);
        /**
         * 画点击事件
         * */
        if (coordinate != null && isFlag) {
            drawCoordinate(canvas);
        }
    }

    /**
     * 画白色背景
     */
    private void drawGrayBackground(Canvas canvas) {
        whitePaint.setStyle(Paint.Style.FILL);
        canvas.drawRect(0, 0, getWidth(), getHeight(), whitePaint);
    }

    /**
     * 画x坐标文字
     * @param canvas
     */
    private void drawXCoordinateText(Canvas canvas) {
        float x = margin + (margin / 9) * 7;
        float y = margin + (margin / 4) * 3;
        switch (model) {
            case MODEL_YEAR: // 年份
                canvas.drawText("(月)", 13 * averageWidth + x, viewHeigth + y, textPaint);
                for (int i = 0; i < 13; i++) {
                    canvas.drawText(String.valueOf(i), i * averageWidth + x, viewHeigth + y, textPaint);
                }
                break;
            case MODEL_MONTH: // 月份
                canvas.drawText("(天)", days * averageWidth + x, viewHeigth + y, textPaint);
                for (int i = 0; i < days; i++) {
                    if ( i % 2 == 0) {
                        canvas.drawText(String.valueOf(i), i * averageWidth + x, viewHeigth + y, textPaint);
                    }
                }
                break;
        }
    }

    /**
     * 画y轴坐标值
     * @param canvas
     */
    private void drawYCoordinateNumber(Canvas canvas) {
        float y = margin + margin / 3;
        /**
         * 设置Y轴单位
         * 及坐标
         */
        switch (model) {
            case MODEL_YEAR: // 年份
                canvas.drawText("(100单)", margin, margin, textPaint);
                for (int i = 1; i < 11; i++) {
                    canvas.drawText(String.valueOf(i), margin, (float) (11 - i) * averageHeigth + y, textPaint);
                }
                break;
            case MODEL_MONTH: // 月份
                canvas.drawText("(单)", margin, margin, textPaint);
                for (int i = 1; i < 11; i++) {
                    canvas.drawText(String.valueOf(i * 10), margin / 4 * 3, (float) (11 - i) * averageHeigth + y, textPaint);
                }
                break;
        }
    }

    /**
     * 画X坐标上横线
     * 只画最左边一条
     * @param canvas
     */
    private void drawXCoordinateLine(Canvas canvas) {
        float x = margin * 2;
        float y = margin + margin / 5;
        switch (model) {
            case MODEL_YEAR: // 年份
                canvas.drawLine(x, x, x, viewHeigth + margin, lienPaint);
                for (int i = 1; i < 13; i++) {
                    canvas.drawLine(x + averageWidth * i, averageHeigth * 11 + margin, averageWidth * i + x, viewHeigth + y, lienPaint);
                }
                break;
            case MODEL_MONTH: // 月份
                canvas.drawLine(x, margin, x, viewHeigth + margin, lienPaint);
                for (int i = 1; i < days; i++) {
                    canvas.drawLine(x + averageWidth * i, averageHeigth * 11 + margin, averageWidth * i + x, viewHeigth + y, lienPaint);
                }
                break;
        }
    }

    /**
     * 画Y坐标上横线
     * 只画最底下一条
     * @param canvas
     */
    private void drawYCoordinateLine(Canvas canvas) {
        float x = margin * 2;
//        for (int i = 0; i < 12; i ++) {
//            canvas.drawLine(x, averageHeigth * i + margin, viewWidth + x, averageHeigth * i + margin, lienPaint);
//        }
        canvas.drawLine(x, averageHeigth * 11 + margin, viewWidth + x, averageHeigth * 11 + margin, lienPaint);
    }

    /**
     * 绘制曲线
     */
    private void drawCurveChart(Canvas canvas) {
        curvePath.reset();
        coordinates.clear();
        float x = margin * 2;
        float y = averageHeigth * 11 + margin;
        curvePath.moveTo(x, y);
        int num = 0;
        switch (model) {
            case MODEL_YEAR:
                num = 13;
                break;
            case MODEL_MONTH:
                num = days;
                break;
        }
        Log.d("TAG", "共有数据：" + num);
        for (int i = 1; i < num ; i++) {
            Log.d("TAG", "加载数据数据i：" + i);
            int s = (int)(Math.random() * 10+1);
            Log.d("TAG", "加载数据数据s：" + s);
            getCoordinate(i, s);
        }
        canvas.drawPath(curvePath, bluePaint);
    }

    /**
     * 根据传入的值获取曲线坐标
     * @param i
     */
    private void getCoordinate(int i, int s) {
        float x = margin * 2;
        float y = averageHeigth * 11 + margin;
        if (s == 0) {
            s = 1;
        }
        x = x + i * averageWidth;
        y = y - s * averageHeigth;
        curvePath.lineTo(x, y);
        Coordinate coordinate = new Coordinate();
        coordinate.setX(x);
        coordinate.setY(y);
        coordinates.add(coordinate);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        /**
         * 曲线点击事件
         */
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            if (coordinates.size() > 0) {
                for (Coordinate coordinate : coordinates) {
                    if ((coordinate.getX() - 20 <= event.getX() && coordinate.getX() + 20 >= event.getX())
                            && (coordinate.getY() - 20 <= event.getY() && coordinate.getY() + 20 >= event.getY())) {
                        isFlag = true;
                        this.coordinate = coordinate;
                        invalidate();
                    }
                }
            }
        }
        return true;
    }

    /**
     * 绘制点击位置
     * @param canvas
     */
    private void drawCoordinate(Canvas canvas) {
        // 设置点击事件为未点击
        isFlag = false;
        //获取文字区域的矩形大小，以便确定文字正中间的位置
        Rect rect = new Rect();
        float y = averageHeigth * 11 + margin;
        float s = (y - coordinate.getY()) / averageHeigth;
        String pers = String.valueOf(s);
        coordinatePaint.getTextBounds(pers, 0, pers.length(), rect);// 确定文字的宽度

        canvas.drawRect(coordinate.getX() - rect.width() / 2  - 20, coordinate.getY() - rect.height() - 40,
                coordinate.getX() + rect.width() / 2  + 20, coordinate.getY(), garyPaint);

        canvas.drawText(pers, coordinate.getX() - rect.width() / 2, coordinate.getY() - rect.height(), coordinatePaint); // 灰色背景
    }

    @Override
    public void onWindowFocusChanged(boolean hasWindowFocus) {
        if (hasWindowFocus) {
            haveFocuse = true;
            initMeasure();
            setModel(this.model);
        }
        super.onWindowFocusChanged(hasWindowFocus);
    }

    /**
     * 坐标点
     */
    class Coordinate {

        private float x;
        private float y;

        public float getX() {
            return x;
        }

        public void setX(float x) {
            this.x = x;
        }

        public float getY() {
            return y;
        }

        public void setY(float y) {
            this.y = y;
        }
    }
}
